package com.dbms.common;

/**
 * SQL错误信息类，用于封装在SQL解析和分析过程中遇到的所有错误。
 *
 * 【关键修改】
 * 此类现在继承自 `RuntimeException`，而不是一个普通的类。
 * 这意味着它是一个“非受检异常”（unchecked exception）。这样做的好处是：
 * 1.  简化代码：在编译器（词法/语法/语义分析器）的深层调用中，如果发现错误，可以直接 `throw new SqlError(...)`，
 * 而不需要在每一层方法签名上都声明 `throws SqlError`。
 * 2.  集中处理：异常可以一直冒泡到最上层的调用者（例如 `DbmsCore.processSql` 方法）再进行捕获和处理，
 * 使得错误处理逻辑更集中。
 */
public class SqlError extends RuntimeException {
    // 错误的类型（词法、语法或语义）
    private final Constants.ErrorType errorType;
    // 错误在原始SQL字符串中的精确位置
    private final Position position;
    // 错误的具体描述信息。这个字段现在由父类 `RuntimeException` 的 `message` 字段来管理。

    /**
     * SqlError 的构造函数。
     * @param errorType 错误的类型。
     * @param position  错误的位置。
     * @param message   错误的描述。
     */
    public SqlError(Constants.ErrorType errorType, Position position, String message) {
        // 调用父类 RuntimeException 的构造函数，将一个格式化后的、包含所有信息的完整错误字符串传递给它。
        // 这样，调用 getMessage() 时就能得到如 "[SYNTAX_ERROR] 在 行: 1, 列: 25: 缺少分号" 这样的完整信息。
        super(String.format("[%s] 在 %s: %s", errorType, position, message));
        this.errorType = errorType;
        this.position = position;
    }

    // --- Getter 方法 ---

    public Constants.ErrorType getErrorType() {
        return errorType;
    }

    public Position getPosition() {
        return position;
    }

    // `getMessage()` 方法现在由父类 `RuntimeException` 提供，它会返回我们在 super() 中设置的完整错误字符串。

    /**
     * 重写 toString 方法，使其直接返回完整的错误消息，方便打印和日志记录。
     */
    @Override
    public String toString() {
        // 直接返回父类中存储的完整消息即可。
        return getMessage();
    }
}